import urllib
import urllib2
from mbserver.server_lib.server import Server
from mbserver.source.models import Source, Group
from mbserver.cache.models import Key, Value
from mbserver.server.lib import utils
import time
import simplejson

class Search:

    def __init__(self, keywords, timeout=4, sources=None, groups=None):

        self.source_array = []
        self.keywords = keywords
        self.timeout = timeout
        self.started = False
        self.start_time = 0

        if sources is not None or groups is not None:
            if sources is not None:
                self.source_array = sources
        
            if groups is not None:
                #Append all the sources that belong to the selected groups
                for group in groups:
                    g = Group.objects.get(id=group)
                    for source in g.source_set.values():
                        self.source_array.append(int(source['id']))
        else:
            #Get all the sources
            sources = Source.objects.all()
            for source in sources:
                self.source_array.append(source.id)

    def do_search(self):
        """
            Metabus server works as an asynchronous server. It's only possible 
            to retrive any results after the timeout.
        """

        values = {
                    'sources' : simplejson.dumps(self.source_array),
                    'keyword' : self.keywords.encode('utf8'),
                 }
    
        # Get a server in a RR queue
        server = Server()
        url = server.get() + 'server/process/'
        
        data = urllib.urlencode(values)
        req = urllib2.Request(url, data)
        response = urllib2.urlopen(req)

        self.started = True
        self.start_time = time.time()

    def get_results(self):
        """
            This method blocks until the timeout has passed
        """
        # Source arrays
        returned = []
        to_be_returned = []

        k = utils.get_formated_keywords(utils.safe_unicode(self.keywords))
        keys = Key.objects.select_related().filter(keyword=k, source__in=self.source_array)

        # wait for timeout
        while ((self.start_time + self.timeout) > time.time()) and len(keys) != len(self.source_array):
            time.sleep(1)
            keys = Key.objects.select_related().filter(keyword=k, source__in=self.source_array)

        entries = []
        for key in keys:
            entries.extend(key.value_set.values())
            returned.append(key.source_id)

        for source_id in self.source_array:
            if not int(source_id) in returned:
                to_be_returned.append(source_id)

        return entries, Source.objects.filter(id__in=to_be_returned)
